package com.tencent.wxcloudrun.schedule;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

import javax.annotation.Resource;

import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import com.alibaba.fastjson2.JSONObject;
import com.tencent.wxcloudrun.constant.RedisKeyConstant;
import com.tencent.wxcloudrun.domain.TActi;
import com.tencent.wxcloudrun.dto.ActiRewardReqDTO;
import com.tencent.wxcloudrun.dto.StoreProdAttrReqDTO;
import com.tencent.wxcloudrun.enums.ActiJoinStatEnum;
import com.tencent.wxcloudrun.enums.ActiJoinTypeEnum;
import com.tencent.wxcloudrun.manager.ActiManager;
import com.tencent.wxcloudrun.service.TActiJoinProdAttrService;
import com.tencent.wxcloudrun.service.TActiJoinService;
import com.tencent.wxcloudrun.service.TActiService;
import com.tencent.wxcloudrun.util.NumberUtils;
import com.tencent.wxcloudrun.util.RedisUtil;
import com.tencent.wxcloudrun.vo.response.acti.ActiQueryResVo;
import com.tencent.wxcloudrun.vo.response.store.StoreProdQueryResVo;

import lombok.extern.slf4j.Slf4j;

/**
 * @author Ryan Zhao
 *         <p>
 *         Copyright: Copyright (c) 2023
 *         </p>
 * @version 1.0
 * @date 2023-08-22 12:21
 * @description: 活动结束任务
 */
@Slf4j
@Component
public class ActiEndJob implements Job {

    @Resource
    private RedisUtil redisUtil;

    @Resource
    private ActiManager actiManager;

    @Resource
    private TActiService actiService;

    @Resource
    private TActiJoinService actiJoinService;

    @Resource
    private TActiJoinProdAttrService actiJoinProdAttrService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void execute(JobExecutionContext jobExecutionContext) {
        String actiIdStr = Objects.toString(jobExecutionContext.getJobDetail().getJobDataMap().get("param"));
        Long actiId = Long.valueOf(actiIdStr);
        log.info("活动结束定时任务-处理开始-活动序号=[{}]", actiId);

        // 活动结束
        actiService.actiEnd(actiId);

        // 更新缓存
        actiManager.saveRedis4Acti(actiId, false);

        TActi acti = actiService.getById(actiId);
        if (Objects.isNull(acti)) {
            return;
        }
        // 如果是摇号
        if (acti.getActiJoinType() == ActiJoinTypeEnum.SHAKE.getValue()) {
            // 生成中选号码
            Map<Long, List<Integer>> numberMap = getRandomNumber(acti);
            // 查询中选用户列表
            List<Long> userIdList = actiJoinProdAttrService.actiEnd(actiId, numberMap);
            // 更新用户参选状态
            actiJoinService.actiEnd(actiId, userIdList);
            // 更新缓存
            if (!CollectionUtils.isEmpty(userIdList)) {
                Map<String, String> redisMap = new HashMap<>();
                for (Long userId : userIdList) {
                    String key = RedisKeyConstant.getActiJoinStatusRedisKey(actiId, userId);
                    redisMap.put(key, String.valueOf(ActiJoinStatEnum.ALREADY_CHOOSE.getValue()));
                }
                redisUtil.multiSet(redisMap);
            }
        }

        log.info("活动结束定时任务-处理成功");
    }

    /**
     * @Author: ZhaoZiYin
     * @Date: 2025/5/7
     * @Params: [actiId]
     * @Return: Map<Long, List<Integer>>
     * @Description: 获取中选号码
     */
    private Map<Long, List<Integer>> getRandomNumber(TActi acti) {
        // 按活动-商品-规格-进行摇号
        String resVoStr = redisUtil.get(RedisKeyConstant.getActiInfoRedisKey(acti.getId()));
        if (!StringUtils.hasLength(resVoStr)) {
            return null;
        }
        ActiQueryResVo resVo = JSONObject.parseObject(resVoStr, ActiQueryResVo.class);
        if (CollectionUtils.isEmpty(resVo.getRewardList())) {
            return null;
        }
        Map<Long, List<Integer>> numberMap = new HashMap<>();
        for (ActiRewardReqDTO storeReqDTO : resVo.getRewardList()) {
            if (storeReqDTO.getActiRewardType() != 1) {
                continue;
            }
            String prodStr = redisUtil.get(RedisKeyConstant.getStoreProdRedisKey(storeReqDTO.getActiRewardKey()));
            if (!StringUtils.hasLength(prodStr)) {
                continue;
            }
            StoreProdQueryResVo storeProdResVo = JSONObject.parseObject(prodStr, StoreProdQueryResVo.class);
            if (CollectionUtils.isEmpty(storeProdResVo.getProdAttrList())) {
                continue;
            }
            for (StoreProdAttrReqDTO prodAttrReqDTO : storeProdResVo.getProdAttrList()) {
                String joinMaxNumber = redisUtil.get(RedisKeyConstant.getActiJoinNumberRedisKey(acti.getId(),
                    storeReqDTO.getActiRewardKey(), prodAttrReqDTO.getProdAttrId()));
                List<Integer> numberList =
                    NumberUtils.getRandomNumber(1, Integer.parseInt(joinMaxNumber) + 1, prodAttrReqDTO.getStock());
                numberMap.put(prodAttrReqDTO.getProdAttrId(), numberList);
            }
        }
        return numberMap;
    }
}
